package net.linku.converter;

import com.alibaba.fastjson.JSONObject;
import net.linku.annotation.ChangeRecordEnums;
import net.linku.annotation.enums.ChangeSourceEnum;
import net.linku.annotation.vo.ChangeRecordBizVO;
import net.linku.domain.LAChangeRecord;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * {@code ChangeRecordMapper} 接口使用 MapStruct 进行对象之间的转换。
 * <p>
 * 该接口定义了从 {@link ChangeRecordBizVO} 到 {@link LAChangeRecord} 的转换方法。
 * MapStruct 自动实现这些转换方法，以便于在业务逻辑层中使用。
 * </p>
 * <p>
 * 使用 {@link #convertDo(List)} 方法可以将一个 {@code List<ChangeRecordBizVO>} 转换为一个 {@code List<LAChangeRecord>}。
 * </p>
 * <p>
 * 该接口使用 MapStruct 的 {@link Builder} 注解禁用构建器模式。这样做是为了简化接口的实现，
 * 如果需要更复杂的构建逻辑，可以根据实际情况调整 {@code Builder} 注解的配置。
 * </p>
 * <p>
 * {@code ChangeRecordMapper} 的实例通过 {@link Mappers#getMapper(Class)} 方法获取，该方法会创建一个实现类并返回实例。
 * </p>
 */
@Mapper(builder = @Builder(disableBuilder = true))
public interface ChangeRecordMapperConverter {

    ChangeRecordMapperConverter INSTANCE = Mappers.getMapper(ChangeRecordMapperConverter.class);

    List<LAChangeRecord> convertDo(List<ChangeRecordBizVO> changeRecordDO);

    /**
     * 领域对象转换到实体对象
     * @param changeRecordDO 数据变更对象
     * @return 数据库对象
     */
    @BeanMapping(ignoreByDefault = true)
    @Mapping(target = "businessId", source = "businessId")
    @Mapping(target = "businessType", expression = "java(convertBusinessType(changeRecordDO.getBusinessTypeEnums()))")
    @Mapping(target = "action", expression = "java(convertBusinessAction(changeRecordDO.getActionEnums()))")
    @Mapping(target = "beforeData", source = "beforeData", qualifiedByName = "convertJsonStr")
    @Mapping(target = "afterData", source = "afterData", qualifiedByName = "convertJsonStr")
    @Mapping(target = "changeType", source = "changeType.type")
    @Mapping(target = "changeDesc", source = "changeDesc")
    LAChangeRecord convertDo(ChangeRecordBizVO changeRecordDO);

    @Mapping(target = "changeSourceDesc", source = "changeResource", qualifiedByName = "convertChangeSourceDesc")
    ChangeRecordBizVO convertChangeRecordBo(LAChangeRecord supplierChangeRecordDO);

    List<ChangeRecordBizVO> convertChangeRecordBo(List<LAChangeRecord> supplierChangeRecordDO);

    default String convertBusinessAction(ChangeRecordEnums.ACTION changeRecordEnumsAction) {
        return Optional.ofNullable(changeRecordEnumsAction)
                .map(ChangeRecordEnums.ACTION::getAction)
                .orElse("");
    }

    default String convertBusinessType(ChangeRecordEnums.TYPE changeRecordEnumsType) {
        return Optional.ofNullable(changeRecordEnumsType)
                .map(ChangeRecordEnums.TYPE::getType)
                .orElse("");
    }

    @Named("convertJsonStr")
    default <T> String convertJsonStr(T obj) {
        if (Objects.isNull(obj)) {
            return "";
        }
        return JSONObject.toJSONString(obj);
    }

    @Named("convertChangeSourceDesc")
    default String convertChangeSourceDesc(ChangeSourceEnum changeSourceEnum) {
        return Optional.ofNullable(changeSourceEnum)
                .map(ChangeSourceEnum::getCnName)
                .orElse("");
    }
}
